//
//  GXQRCodeManager.m
//  ScanQRCode
//
//  Created by Ssky on 2016/11/21.
//  Copyright © 2016年 Sky SS. All rights reserved.
//

#import "GXQRCodeManager.h"
//#import <SafariServices/SafariServices.h>

@interface GXQRCodeManager () <AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic,weak) AVCaptureVideoPreviewLayer * pvwLayer;

@end

@implementation GXQRCodeManager


+ (instancetype)manager {
    GXQRCodeManager * _manager = [[self alloc] init];
    return _manager;
}

- (instancetype)init {
    if (self = [super init]) {
        [self startRunning];
    }
    return self;
}


- (BOOL)startRunning {
    //
    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    //lock device
    NSError * errorLock = nil;
    if ([device lockForConfiguration:&errorLock]) {
        
        // 自动对焦
        if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
            [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
        }
        
        // 自动白平衡
        if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
            [device setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
        }
        
        //unlock
        [device unlockForConfiguration];
    }else {
        NSLog(@"%@", errorLock);
        device = nil;
        return NO;
    }
    
    // input
    NSError * errorInput = nil;
    AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&errorInput];
    
    if (!input || errorInput) {
        
        NSLog(@"%@", errorInput);
        return NO;
    }
    
    // output
    AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc] init];
    
    // set output metadataObjectsDelegate
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // session
    AVCaptureSession * session = [[AVCaptureSession alloc] init];
    
    if ([session canAddInput:input]) {
        [session addInput:input];
    }
    
    // Add output and set it`s type.
    if ([session canAddOutput:output]) {
        [session addOutput:output];
        
        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,          //二维码
                                       AVMetadataObjectTypeEAN8Code,        //条形码 EAN8
                                       AVMetadataObjectTypeEAN13Code,       //条形码 EAN13
                                       AVMetadataObjectTypeCode128Code,     //条形码 EAN128
                                       ];
    }
    
    //
    _session = session;
    
    return YES;
}

- (void)stopRunning {
    [self.session stopRunning];
    _session = nil;
    
    [self.pvwLayer removeFromSuperlayer];
}


#pragma mark - delegates

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    //
    for (AVMetadataMachineReadableCodeObject *obj in metadataObjects) {
        //
        BackObjectType objectType;
        
        if ([obj.stringValue hasPrefix:@"http"]) { //网页链接
            //
            objectType = kObjectTypeHyperlink;
            
        }else {
            //
            objectType = kObjectTypeString;
        }
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // call back
            if ([self.codeDelegate respondsToSelector:@selector(gxQRCodeManager:backObject:backObjectType:)]) {
                [self.codeDelegate gxQRCodeManager:self backObject:obj.stringValue backObjectType:objectType];
            }
        });
        
        //停止会话
        [self stopRunning];
        return;
    }
}






#pragma mark - setter & getter

- (void)setPreview:(UIView *)preview {
    _preview = preview;
    
    AVCaptureVideoPreviewLayer * pvwLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    [self.preview.layer insertSublayer:pvwLayer above:self.preview.layer];
    self.pvwLayer = pvwLayer;
    
    [self.session startRunning];
}












@end
